<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>axios入门与源码解析</title>
  <link rel="stylesheet" href="../bootstrap.min.css">
  <!-- <script src="../axios.js"></script> -->
</head>

<body>
  <div class="container">
    <h2>axios基本使用</h2>
    <p>
      <a href="https://github.com/axios/axios">去Git学习axios</a>
    </p>
  </div>
  <script>
    // 构造函数
    function Axios(config){
      this.config = config
      this.interceptors={
        request:new InterceptorManager(),
        response:new InterceptorManager()
      }
    }
    
    // 拦截器管理器构造函数
    function InterceptorManager(){
      this.handers = []
    }
    
    InterceptorManager.prototype.use = function(fulfilled,rejected){
      this.handers.push({
        fulfilled,
        rejected
      })
    }
    
    // request发送请求 重点与难点
    Axios.prototype.request = function(config){
      // 创建一个Promise对象
      let promise = Promise.resolve(config)
      // 创建一个数组
      const chains = [dispatchRequest,undefined]
      // 处理请求拦截器 将请求拦截器的回调unshift到chains中
      this.interceptors.request.handers.forEach(item=>{
        chains.unshift(item.fulfilled,item.rejected)
      })
      // 处理响应拦截器 将响应拦截器的回调push到chains中
      this.interceptors.response.handers.forEach(item=>{
        chains.push(item.fulfilled,item.rejected)
      })
      // 遍历
      while (chains.length>0) {
        promise = promise.then(chains.shift(),chains.shift())
      }
      return promise
    }
    
    // 发送请求
    function dispatchRequest(config){
      return new Promise((resolve,reject)=>{
        resolve({
          status:200,
          statusText:'OK'
        })
      })
    }
    
    // 创建实例
    let context = new Axios({})

    // 创建axios的函数
    let axios = Axios.prototype.request.bind(context)

    // 将contex属性config interceptors添加到axios函数对象上
    Object.keys(context).forEach(key=>{
      axios[key] = context[key]
    })

    // 以下为拦截器测试代码
    // 添加请求拦截器
    axios.interceptors.request.use(function (config) {
      // 修改config中的参数
      config.params = {a:100}
      console.log('请求拦截器--成功-1号')
      return config;
      // throw '参数出错'
    }, function (error) {
      console.log('请求拦截器--失败-1号')
      return Promise.reject(error);
    });
    axios.interceptors.request.use(function (config) {
      // 修改config中的参数
      config.timeout = 1000
      console.log('请求拦截器--成功-2号')
      return config;
      // throw '参数出错'
    }, function (error) {
      console.log('请求拦截器--失败-2号')
      return Promise.reject(error);
    });

    // 添加响应拦截器
    axios.interceptors.response.use(function (response) {
      console.log('响应拦截器--成功-1号')
      console.log(response)
      return response.data;
    }, function (error) {
      console.log('响应拦截器--失败-1号')
      return Promise.reject(error);
    });
    axios.interceptors.response.use(function (response) {
      console.log('响应拦截器--成功-2号')
      return response;
    }, function (error) {
      console.log('响应拦截器--失败-2号')
      return Promise.reject(error);
    });

    axios({
      method:'get',
      url:'http://localhost:3000/comments'
    }).then(res=>{
      console.log('响应成功-成功回调')
      console.log(res)
    }).catch(error=>{
      console.log('响应失败-失败回调')
      console.log('失败原因：',error)
    })
  </script>
</body>

</html>